import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;


public class Wikimap extends Applet implements Runnable, MouseMotionListener{	
	// some constants
	public final static int WIDTH = 640;
	public final static int HEIGHT = 480;	
	
	// The the vars for storing dots
	public Dot center;
	public ArrayList<Dot> dots = new ArrayList<Dot>();
	
	// Mouse position
	public int mousex;
	public int mousey;
	
	// this is used for more efficient checking of whether the mouse
	// is over a circle
	public int mouseSector;
	public boolean displayName;
	
	// called whenever the Applet is loaded
	public void init(){
		// sets the size
		this.setSize(WIDTH, HEIGHT);
		this.setBackground(Color.BLACK);
		
		// makes dots for the first arraylist of article names
		makeDots("1");
		
		// creates the animation thread
		Thread run = new Thread(this);
		run.start();

		// creates a listener for movement of the mouse
		addMouseMotionListener(this);
	}
	
	// draws everything
	// it's important to keep anything more than simple calculations out of 
	// here because it will interfere with animation put that stuff in
	// the calculate() method (or somewhere else)
	public void paint(Graphics g1){
		Graphics2D g = (Graphics2D)g1;
		g.setColor(center.color);
		g.fillOval((int)(center.x-center.radius), (int)(center.y-center.radius), center.radius*2, center.radius*2);
		g.setColor(Color.WHITE);
		g.drawString(center.item, (int)(center.x-((center.item.length()*5)/2)), (int)(center.y+20));
		for(int n = 0; n<dots.size(); n++){
			g.setColor(dots.get(n).color);
			g.fillOval((int)(dots.get(n).x-dots.get(n).radius), (int)(dots.get(n).y-dots.get(n).radius), dots.get(n).radius*2, dots.get(n).radius*2);
		}
		
		g.setColor(Color.WHITE);
		if(displayName){
			g.drawString(dots.get(mouseSector).item, (int)(dots.get(mouseSector).x-5), (int)(dots.get(mouseSector).y+25));
		}
		
		g.drawString("Mouse sector: " + mouseSector, 10, 20);
		
		g.drawString("("+mousex+", "+mousey+")", 10, 40);
	}
	
	
	// all the double buffering stuff... basically just pretend it doesn't exist
	private Image image;
	private Graphics doubleBuffer;	
	public void update(Graphics g){
		if (image == null){
	    	  image = createImage(WIDTH, HEIGHT);
	    	  doubleBuffer = image.getGraphics ();
		}
		
		doubleBuffer.setColor(getBackground ());
		doubleBuffer.fillRect(0, 0, WIDTH, HEIGHT);
		doubleBuffer.setColor(getForeground());
		
		paint(doubleBuffer);
		
		g.drawImage (image, 0, 0, this);
	} 
	// you can stop pretending code doesn't exist right here
	
	
	// manages a thread for updating the applet
	public void run() {
		//Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
		while(true){
			long time = System.currentTimeMillis();
			calculate();
			
			// calls update then paint
			repaint();
			
			try{
				long tmpTime = System.currentTimeMillis()-time;
				if(tmpTime <= 10){
					Thread.sleep(10-tmpTime);
				}
			} catch(InterruptedException ex){
				ex.printStackTrace();
			}
		}
	}
	
	// This will probably be where the positions of dots get updated for the
	// next frame in the animation
	public void calculate(){
		displayName = dots.get(mouseSector).isOver(mousex, mousey);
	}
	
	// this'll probably be called every time you go to a new article
	// because it constructs dot objects for each title in the ArrayList
	public void makeDots(String subject){
		center = new Dot(subject);
		ArrayList<String> temp = Retriever.retrieve(subject);
		for(int n = 0; n < temp.size(); n++){
			dots.add(new Dot(temp.get(n)));
		}
		
		
		// this is just an initial test
		center.x = WIDTH/2;
		center.y = HEIGHT/2;
		for(int n = 0; n<dots.size(); n++){
			dots.get(n).mag = 200;
			dots.get(n).dir = n*(2*Math.PI/dots.size());
			dots.get(n).updateXY();
		}
	}

	// this method is required if you're implementing MouseMotionListener
	// there may be a use later
	public void mouseDragged(MouseEvent arg0) {		
	}
	
	// keeps the mouse position vars up to date
	public void mouseMoved(MouseEvent mEvent) {
		mousex = mEvent.getX();
		mousey = mEvent.getY();
		
		mouseSector = getMouseSector();
	}
	
	// Okay mouseSector makes mouse over checking a lot faster because
	// it makes it so you don't have to check whether the mouse is over
	// every dot.
	// Imagine the circle cut up into pieces like a pizza where each article/dot
	// is in its own piece.  This finds what piece the mouse is in and then
	// you only have to check whether the mouse is over that one dot!
	private int getMouseSector(){
		double angle = Dot.getDir(mousey, mousex);

		// Pwned
		int pwned = (int)Math.round((dots.size())*(angle/(Math.PI*2)));
		if(pwned == dots.size()){
			pwned = 0;
		}
		return pwned;
	}
}
